<template>
  <div class="app-container">
    <div class="search-container">
      <el-form :model="searchParam" :inline="true" label-width="65px">
        <el-form-item label="工厂">
          <el-select
            @keyup.enter="search"
            v-model="searchParam.plantId"
            placeholder="请选择工厂"
            clearable
            @change="selectPlant"
          >
            <el-option
              v-for="item in plantList"
              :key="item.id"
              :label="item.organizationCode"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="工作中心">
          <el-select
            @keyup.enter="search"
            v-model="searchParam.workCenterId"
            placeholder="请选择工作中心"
            clearable
          >
            <el-option
              v-for="item in workShopList"
              :key="item.id"
              :label="`${item.workshopCode}-${item.workshopName}`"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="工作年份">
          <el-select
            @keyup.enter="search"
            v-model="searchParam.planYear"
            placeholder="请选择工作年份"
            clearable
            @change="selectYear"
          >
            <el-option
              v-for="item in yearOptions"
              :key="item"
              :value="item"
              :label="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="工作周">
          <el-select
            @keyup.enter="search"
            v-model="searchParam.planWeek"
            placeholder="请选择工作周"
            clearable
          >
            <el-option
              v-for="item in monthOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <!-- <el-form-item label="生产批次">
          <el-input
            v-model="searchParam.planBatch"
            placeholder="请输入生产批次"
            clearable
            @keyup.enter="search"
          />
        </el-form-item> -->
        <el-form-item>
          <!-- <el-popconfirm
            title="请确认当前数据是否已被保存，切换后未保存的数据会被清空，是否切换?"
            confirm-button-text="切换"
            cancel-button-text="取消"
            :width="300"
            @confirm="startSearch"
          >
            <template #reference>
              <el-button v-show="tableData && tableData.length" type="primary"
                ><i-ep-search />切换</el-button
              >
            </template>
</el-popconfirm>
<el-button v-show="!tableData || !tableData.length" type="primary" @click="startSearch"><i-ep-search />切换</el-button>
-->
          <el-button type="primary" @click="startSearch"
            ><i-ep-search />切换</el-button
          >
          <el-button @click="reset"><i-ep-refresh />重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never" class="table-container">
      <template #header>
        <el-button type="success" @click="addPlan"
          ><i-ep-plus />新增行</el-button
        >
        <el-button @click="weekBatchImport"
          ><template #icon><i-ep-upload /></template>导入周计划</el-button
        >
        <el-button @click="dailyBatchImport"
          ><template #icon><i-ep-upload /></template>导入日计划</el-button
        >
        <el-button class="ml-3" @click="downLoadExcel">
          <template #icon><i-ep-download /></template>导出</el-button
        >

        <div style="float: right">
          <el-button
            type="primary"
            :loading="saveLoading"
            @click="validIsSearched('保存')"
            >保 存</el-button
          >
          <el-button
            type="primary"
            @click="validIsSearched('下达')"
            :loading="issueLoading"
            >下 达</el-button
          >
          <el-button
            type="danger"
            @click="validIsSearched('关闭')"
            :loading="closeLoading"
            >关 闭</el-button
          >
          <el-button
            type="danger"
            @click="validIsSearched('删除')"
            :loading="deleteLoading"
            >删 除</el-button
          >
        </div>
        <!-- 导入周计划 -->
        <ImportExcel ref="weekImportRef" />
        <!-- 导入日计划 -->
        <ImportExcel ref="dailyImportRef" />
      </template>

      <el-form
        ref="formRef"
        :model="tableData"
        :rules="rules"
        label-width="90px"
        style="width: 100%"
        class="require-form planTable"
      >
        <el-table
          ref="dataTableRef"
          v-loading="loading"
          :data="tableData"
          highlight-current-row
          :span-method="(param) => objectSpanMethod(param, 9)"
          :show-summary="true"
          max-height="600"
          border
          :header-cell-style="{ backgroundColor: '#fff' }"
          :summary-method="
            (param) => getSummaries(param, maxCapacityLoad, 9, tableLoadRate)
          "
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" align="center" fixed />
          <el-table-column
            label="物料号//工序-人数-版本号"
            prop="materialId"
            min-width="250"
            show-overflow-tooltip
            align="left"
            fixed
          >
            <template #default="{ $index, row }">
              <!-- 分行校验的关键在于:prop="'grossProfits.' + $index + '.name'" -->
              <el-form-item
                v-if="row.planState == 0"
                :prop="$index + '.routingAllocationId'"
                :rules="rules.routingAllocationId"
                label-width="0px"
              >
                <el-select
                  v-model="row.routingAllocationId"
                  placeholder="请选择"
                  @change="(e) => changeRoutingAllocation(e, $index)"
                  style="width: 100%"
                >
                  <el-option
                    v-for="item in routingAllocationIdList"
                    :key="item.id"
                    :value="item.id"
                    :label="`${item.descriptionCode}-${item.versionNo}`"
                    :disabled="
                      selectedRoutingAllocationIds.indexOf(item.id) !== -1
                    "
                    small
                  />
                </el-select>
              </el-form-item>
              <span v-else>{{
                `${row.descriptionCode}-${row.versionNo}`
              }}</span>
            </template>
          </el-table-column>
          <el-table-column label="卷料" width="60" align="center">
            <template #default="{ row, $index }">
              <svg-icon
                icon-class="material"
                class="text-[17px] !mr-[0px] cursor-pointer color-[#409eff]"
                @click="selectMaterials(row, $index)"
              />
            </template>
          </el-table-column>
          <el-table-column
            label="班产"
            prop="yield"
            width="85"
            show-overflow-tooltip
            align="right"
          />
          <el-table-column
            label="状态"
            prop="planState"
            min-width="100"
            align="center"
          >
            <template #default="scope">
              <el-tag v-show="scope.row.planState == 0" type="success">{{
                useDictionary("PlanStateList", scope.row.planState ?? "")
              }}</el-tag>
              <el-tag v-show="scope.row.planState != 0">{{
                useDictionary("PlanStateList", scope.row.planState ?? "")
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="计划数量"
            prop="planQuantity"
            min-width="140"
            show-overflow-tooltip
            align="center"
          >
            <template #default="{ $index, row }">
              <!-- 分行校验的关键在于:prop="'grossProfits.' + $index + '.name'" -->
              <el-form-item
                v-if="row.planState == 0"
                :prop="$index + '.planQuantity'"
                :rules="rules.planQuantity"
                label-width="0px"
              >
                <el-input
                  v-model="row.planQuantity"
                  placeholder="请输入"
                  clearable
                  small
                  :disabled="
                    !row.requestPlanList || row.requestPlanList?.length === 0
                  "
                  @change="(e) => changePlanQuantity(e, $index)"
                >
                  <template
                    #append
                    v-if="row.requestPlanList && row.requestPlanList.length"
                    ><el-button
                      :loading="row.autoAllocationLoading"
                      link
                      class="m-0 text-[12px] cursor-pointer autoAllocation"
                      style="margin: 0px !important"
                      @click="rulePlanQuantity(row.planQuantity, $index)"
                      >分配</el-button
                    >
                  </template>
                </el-input>
              </el-form-item>
              <span v-else>{{ row.planQuantity }}</span>
            </template>
          </el-table-column>

          <el-table-column
            label="生产批次"
            prop="planBatch"
            min-width="100"
            show-overflow-tooltip
            align="center"
          >
            <template #default="{ $index, row }">
              <!-- 分行校验的关键在于:prop="'grossProfits.' + $index + '.name'" -->
              <el-form-item
                v-if="row.planState == 0"
                :prop="$index + '.planBatch'"
                :rules="rules.planBatch"
                label-width="0px"
              >
                <el-input
                  v-model="row.planBatch"
                  placeholder="请输入"
                  clearable
                  small
                />
              </el-form-item>
              <span v-else>{{ row.planBatch }}</span>
            </template>
          </el-table-column>

          <el-table-column
            label="未排数量"
            prop="unPlanQuantity"
            width="85"
            show-overflow-tooltip
            align="right"
          />

          <el-table-column
            label="已完成数量"
            prop="planFinishQuantity"
            width="95"
            show-overflow-tooltip
            align="right"
          />
          <el-table-column label="" width="60" align="center">
            <template #default="{ row, $index }">
              <span class="text-[13px]" v-if="($index + 1) % 2 !== 0"
                >计划</span
              >
              <span class="text-[13px]" v-else>实际</span>
            </template>
          </el-table-column>

          <el-table-column :label="`CW${searchParam.planWeek}`" align="center">
            <template #default="">
              <el-table-column
                v-for="(item, index) in currentWeekDetail"
                :key="index"
                :label="`${item.date} 周${ToChineseDate(item.week)}`"
                :label-class-name="`${item.isFree ? 'bg-free' : ''}`"
              >
                <el-table-column
                  v-for="(monthItem, monthIndex) in classCount"
                  :label="`${convertToChineseNumber(monthItem, 2)}班`"
                  :key="monthIndex"
                  :prop="`planQuantity_${index}_${monthIndex}`"
                  class-name="percent_cell"
                  header-align="center"
                  align="right"
                  :label-class-name="`${item.isFree ? 'bg-free' : ''}`"
                >
                  <template #default="{ row, $index }">
                    <div
                      v-if="($index + 1) % 2 !== 0"
                      @click="
                        open(
                          row,
                          $index,
                          index,
                          monthIndex,
                          row?.newOrders[index]?.newClasses[monthIndex]
                            ?.planQuantity
                        )
                      "
                    >
                      <span
                        :class="
                          row?.newOrders[index]?.newClasses[monthIndex]
                            ?.planState == 5
                            ? 'text-coolGray'
                            : ''
                        "
                      >
                        {{
                          row?.newOrders[index]?.newClasses[monthIndex]
                            ?.planQuantity ?? ""
                        }}
                      </span>
                    </div>
                    <!-- fef0f0 -->
                    <div v-else class="bg-[#fef0f0]">
                      <span
                        :class="
                          row?.newOrders[index]?.newClasses[monthIndex]
                            ?.planState === 5
                            ? 'text-coolGray'
                            : ''
                        "
                      >
                        {{
                          row?.newOrders[index]?.newClasses[monthIndex]
                            ?.planFinishQuantity ?? ""
                        }}
                      </span>
                    </div>
                  </template>
                </el-table-column>
              </el-table-column>
            </template>
          </el-table-column>

          <!-- <el-table-column
            label="操作"
            width="120"
            align="center"
            fixed="right"
          >
            <template #default="{ row, $index }">
              <el-button
                type="danger"
                link
                class="text-[13px]"
                @click="deletePlan($index)"
                >删除</el-button
              >
              <el-button
                type="danger"
                link
                class="text-[13px]"
                @click="deletePlan($index)"
                >关闭</el-button
              >
            </template>
          </el-table-column> -->
        </el-table>
      </el-form>
    </el-card>
    <SelectMaterialPlanDialog
      v-model:visible="materialsSelect.visible"
      :data="materialsSelect.data"
      :allocationId="materialsSelect.allocationId"
      :eldIds="materialsSelect.eldIds"
      :readonly="materialsSelect.readonly"
      :isMultiple="true"
      :plantId="searchedParams?.plantId"
      :companyId="searchedCompanyId"
      :rowIndex="materialsSelect?.rowIndex"
      @echo-info="getMaterialsSelect"
    />
    <el-dialog
      :close-on-click-modal="false"
      v-model="dialogVisible"
      title="计划排产数量"
      width="450"
      align-center
      draggable
      class="planDialog"
      @close="clearRuleForm"
    >
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        :rules="rulesPlan"
        label-width="auto"
        label-position="left"
        class="demo-ruleForm"
        status-icon
      >
        <div class="mb-[6px]">
          {{ `未排产数量：${ruleForm.unPlanQuantity}` }}
        </div>
        <el-form-item prop="quantity">
          <el-input
            v-model="ruleForm.quantity"
            placeholder="请输入计划排产数量"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="clearRuleForm">取消</el-button>
          <el-button type="primary" @click="submitPlanQuantity">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { useDownload, useDictionary } from "@/utils/useTable";
import request from "@/utils/request";
import SelectMaterialPlanDialog from "@/views/mes/weeklyProducePlan/components/select-material-plan-dialog.vue";
import { useUserStore } from "@/store/modules/user";
import {
  getPlantList,
  getFirstWorkShopList,
  getWorkCenterDetail,
  getCurrentYield,
  getFreeDetails,
  getMonthList,
  getYearList,
  getMaterialList,
  getDateshiftCount,
} from "@/utils/commonData";
import { getWeekNumber } from "@/utils/dateUtils";
import { convertToChineseNumber, validateNumber } from "@/utils/commonHooks";
import {
  getOneLineDate,
  WeekDetailType,
  SearchType,
  resolveSearchData,
  resolveSaveData,
  ToChineseDate,
  getCurrentWeekDetail,
  objectSpanMethod,
  calculateLoadRate,
  getSummaries,
  deepCopy,
} from "./index";

// 页面定义
defineOptions({
  name: "MESWEEKLYPRODUCEPLAN",
  inheritAttrs: false,
});

// 获取登陆人工厂信息
const userPlantInfo = computed(() =>
  useUserStore().userPlantInfo ? JSON.parse(useUserStore().userPlantInfo) : {}
);

// 输入计划数量、弹窗校验
const dialogVisible = ref(false);
const ruleForm: any = reactive({
  quantity: "",
  rowData: null,
  rowIndex: null,
  monthIndex: null,
  cellIndex: null,
  unPlanQuantity: null,
});

// 输入计划数量是否合规
const checkPlanQuantity = (rule: any, value: any, callback: any) => {
  // 可以为空
  if (!value) {
    return callback();
  }

  // 校验是否为数字
  const commonValue = Number(value);
  if (Number.isNaN(commonValue) && value) {
    return callback(`请输入数字`);
  }

  // 校验不能为复数
  if (commonValue < 0) {
    return callback(`请输入正确的数字`);
  }

  // 校验总数是否超过计划数量
  const { rowIndex, monthIndex, cellIndex } = ruleForm;
  const computedTableData = deepCopy(toRaw(tableData.value)); // 操作的tabledata
  let sumPlanCount = 0;
  computedTableData[rowIndex].newOrders.map((item, itemIndex) => {
    item.newClasses.map((cellItem, newIndex) => {
      if (cellItem.planQuantity) {
        // 当前数据不添加
        if (monthIndex === itemIndex && cellIndex === newIndex) {
        } else {
          sumPlanCount += cellItem.planQuantity * 1;
        }
      }
    });
  });
  if (sumPlanCount + value * 1 > computedTableData[rowIndex].planQuantity * 1) {
    const maxCount =
      computedTableData[rowIndex].planQuantity * 1 - sumPlanCount * 1;
    console.log(
      maxCount,
      sumPlanCount + value * 1,
      computedTableData[rowIndex].planQuantity * 1
    );
    return callback(
      `不能超过${parseInt(maxCount)},当前行计划之和不能超过总计划数量`
    );
  }

  let elderData: any = deepCopy(toRaw(tableData.value));
  elderData[rowIndex].newOrders[monthIndex].newClasses[cellIndex].planQuantity =
    value;
  elderData[rowIndex + 1].newOrders[monthIndex].newClasses[
    cellIndex
  ].planQuantity = value;

  const result = resolveSaveData(elderData);

  calculateLoadRate(result)
    .then((res: any) => {
      console.log("res", res, res[monthIndex * 3 + cellIndex]);
      const currentLoad = res[monthIndex * 3 + cellIndex] ?? "";
      if (Number(currentLoad) > maxCapacityLoad.value / 100) {
        return callback(
          `负荷率不能超过${(maxCapacityLoad.value / 100).toFixed(
            2
          )}，当前负荷率为${currentLoad}请重新分配`
        );
      } else {
        return callback();
      }
    })
    .catch(() => {
      return callback();
    });
};

const rulesPlan = reactive({
  quantity: [{ validator: checkPlanQuantity, trigger: "blur" }],
});

// 清空弹窗校验
function clearRuleForm() {
  ruleFormRef.value.clearValidate();
  dialogVisible.value = false;
  ruleForm.rowIndex = null;
  ruleForm.monthIndex = null;
  ruleForm.cellIndex = null;
  ruleForm.rowData = null;
  ruleForm.quantity = "";
}

// 确认输入计划数量
const ruleFormRef = ref();
const submitPlanQuantity = () => {
  if (!ruleFormRef.value) return;
  ruleFormRef.value.validate(async (valid) => {
    if (valid) {
      const { rowIndex, monthIndex, cellIndex, rowData, quantity } = ruleForm;
      let elderData: any = deepCopy(toRaw(tableData.value));
      elderData[rowIndex].newOrders[monthIndex].newClasses[
        cellIndex
      ].planQuantity = quantity ?? 0;
      elderData[rowIndex + 1].newOrders[monthIndex].newClasses[
        cellIndex
      ].planQuantity = quantity ?? 0;

      const result = resolveSaveData(elderData);

      tableLoadRate.value = await calculateLoadRate(result);
      // 修改第一行
      tableData.value[rowIndex].newOrders[monthIndex].newClasses[
        cellIndex
      ].planQuantity = quantity;
      // 修改第二行
      tableData.value[rowIndex + 1].newOrders[monthIndex].newClasses[
        cellIndex
      ].planQuantity = quantity;
      computedUnPlanQuantity(rowIndex);
      clearRuleForm();
    } else {
      console.log("error submit!");
    }
  });
};

// 定义钢卷选择选择器弹窗参数
const materialsSelect = reactive<DialogOption>({
  allocationId: "",
  rowIndex: "",
  visible: false,
  eldIds: [],
  data: [],
});
const materialsOptions: any = ref([]); // 选择器 list
// 接收钢卷选择器回调参数
function getMaterialsSelect(options: any, index: number) {
  // 新建的计划，可以修改
  if (tableData.value[index].planState == 0) {
    materialsOptions.value = options;
    console.log("接收钢卷选择器回调", options);
    tableData.value[index].requestPlanList = options;
    tableData.value[index + 1].requestPlanList = options;

    if (options.length) {
      let sumQuantity = 0;
      options.map((item) => {
        sumQuantity += item.theoryQuantity ?? 0;
      });
      tableData.value[index].planQuantity = sumQuantity;
      tableData.value[index + 1].planQuantity = sumQuantity;
      tableData.value[index].requestPlanList = options;
      tableData.value[index + 1].requestPlanList = options;
    } else {
      tableData.value[index].planQuantity = "";
      tableData.value[index + 1].planQuantity = "";
      tableData.value[index].requestPlanList = [];
      tableData.value[index + 1].requestPlanList = [];
    }
  }
}

/** 定义form信息 */
const rules = reactive({
  routingAllocationId: [
    { required: true, message: "请选择", trigger: "change" },
  ],
  planQuantity: [
    { required: true, message: "请输入", trigger: "blur" },
    {
      validator: validateNumber,
      trigger: "blur",
    },
  ],
  planBatch: [
    { required: true, message: "请输入", trigger: "blur" },
    {
      validator: validateNumber,
      trigger: "blur",
    },
  ],
});

const formRef = ref(ElForm);
const currentYear = new Date().getFullYear(); // 当前年份
const currentWeek = getWeekNumber(new Date()); // 当前第几周
const classCount = 3; // 固定三个班次

// 表格日期对象 [{date: '05/06', week: 1}, {date: '05/07', week: 2}...]
const currentWeekDetail: any = ref<WeekDetailType[]>([]);
const freeDayDetail: any = ref([]);

// 初始化搜索参数数据
const searchParamInit = {
  planWeek: currentWeek,
  planYear: currentYear,
  workCenterId: "",
  plantId: userPlantInfo.value?.id || "",
  planBatch: "",
};

const searchedParams = ref();

const isSearched = ref(false); // 是否已搜索
let tableData: any = ref([]); // 表格数据

// 操作前，校验是否切换
function validIsSearched(type) {
  if (!isSearched.value) {
    ElMessage.error("请切换到对应排产后，再操作");
    return;
  } else {
    if (type === "保存") {
      savePlan(tableData.value, "保存");
    } else if (type === "下达") {
      issueOrders();
    } else if (type === "关闭") {
      closePlan();
    } else if (type === "删除") {
      deletePlan();
    }
  }
}
// 添加表格行
function addPlan() {
  if (!isSearched.value) {
    ElMessage.error("请切换到对应排产后，再添加");
    return;
  } else {
    const oneTable = getOneLineDate(
      currentWeekDetail.value,
      searchParam.value.planYear,
      currentYield.value,
      searchedParams.value
    );
    tableData.value = [...toRaw(tableData.value), oneTable[0], oneTable[1]];
  }
}

const ids = ref<string[]>([]);

/** 行复选框选中  */
function handleSelectionChange(selection: any) {
  // 存入唯一值，已保存过的存id, 未保存过的存key
  ids.value = selection.map((item: any) => item.id || item.key);
}

// 批量关闭
const closeLoading = ref(false);
function closePlan() {
  if (!ids.value.length) {
    ElMessage.warning("请选择数据");
    return;
  } else {
    ElMessageBox.confirm(
      "未下达数据不能关闭，请确认是否关闭所选数据?",
      "提示",
      {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      }
    )
      .then(async () => {
        let listIds: any = ""; //第几行数据  不能关闭提示
        const resultTableData = deepCopy(toRaw(tableData.value));
        resultTableData.map((item: any, index: number) => {
          if (
            item.planState * 1 === 0 &&
            (ids.value.indexOf(item.id) !== -1 ||
              ids.value.indexOf(item?.key) !== -1)
          ) {
            if (index % 2 === 0) {
              const newLine = (index + 2) / 2;
              listIds += `第${newLine}行、`;
            }
          } else if (
            item.planState * 1 > 0 &&
            ids.value.indexOf(item.id) !== -1
          ) {
            item.planState = 5;
          }
        });
        if (listIds.length) {
          // 提示未下达过的计划，不能关闭
          listIds = listIds.slice(0, listIds.length - 1);
          ElMessage.error(`${listIds}未下达，不能关闭，请重新选择`);
          return;
        }
        // 走关闭成功状态更新接口保存计划
        savePlan(resultTableData, "关闭");
        // ElMessage.success("批量关闭成功");
      })
      .catch(() => {
        ElMessage({
          type: "info",
          message: "取消关闭",
        });
      });
  }
}

// 批量删除
const deleteLoading = ref(false);
function deletePlan() {
  const idsSave = deepCopy(toRaw(ids.value));
  if (!ids.value.length) {
    ElMessage.warning("请选择数据");
    return;
  } else {
    ElMessageBox.confirm("请确认是否删除所选数据?", "提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(async () => {
        const tableDatas: any = [];
        // const resultTableData = deepCopy(toRaw(tableData.value));
        tableData.value.map((item: any) => {
          if (ids.value.indexOf(item?.key) !== -1 && item.id === "") {
          } else if (ids.value.indexOf(item.id) !== -1) {
            item.deleted = 1;
            tableDatas.push(item);
          } else {
            tableDatas.push(item);
          }
        });
        tableData.value = tableDatas;
        getSelectedAllocationIds();
        // 走删除状态更新接口保存计划
        if (tableData.value.length) {
          // 走删除状态更新接口保存计划
          savePlan(tableData.value, "删除", idsSave);
        }
        // ElMessage.success("批量下达成功");
      })
      .catch(() => {
        ElMessage({
          type: "info",
          message: "取消删除",
        });
      });
  }
}

// 批量下达
const issueLoading = ref(false);
function issueOrders() {
  // console.log("ids", ids);
  if (!ids.value.length) {
    ElMessage.warning("请选择数据");
    return;
  } else {
    ElMessageBox.confirm("请确认是否下达所选数据?", "提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(async () => {
        let listIds: any = ""; //第几行数据  不能下达提示
        const resultTableData = deepCopy(toRaw(tableData.value));
        resultTableData.map((item: any, index: number) => {
          if (item.planState * 1 > 0 && ids.value.indexOf(item.id) !== -1) {
            if (index % 2 === 0) {
              const newLine = (index + 2) / 2;
              listIds += `第${newLine}行、`;
            }
          } else if (
            item.planState * 1 === 0 &&
            ids.value.indexOf(item.id) !== -1
          ) {
            item.planState = 2;
          } else if (
            item.planState * 1 === 0 &&
            ids.value.indexOf(item.key) !== -1 &&
            !item.id
          ) {
            item.planState = 2;
          }
        });
        if (listIds.length) {
          // 提示已下达过的计划，不能重复下达
          listIds = listIds.slice(0, listIds.length - 1);
          ElMessage.error(`${listIds}不能重新下达，请重新选择`);
          return;
        }
        // 走下达状态更新接口保存计划
        savePlan(resultTableData, "下达");
        // ElMessage.success("批量下达成功");
      })
      .catch(() => {
        ElMessage({
          type: "info",
          message: "取消下达",
        });
      });
  }
}

const currentYield = ref(); // 当前班产
const searchParam = ref<SearchType>({ ...searchParamInit });
const loading = ref(false);
const elderData: any = ref();

const tableLoadRate: any = ref([]);

// 搜索
const search = async () => {
  loading.value = true;
  tableData.value = [];
  const { data } = await request({
    url: "/mes/mesworkorder/queryByWeek",
    method: "post",
    data: toRaw(searchParam.value),
  }).catch(() => {
    loading.value = false;
  });

  // 获取接口原数据
  elderData.value = deepCopy(data ?? []);

  searchedCompanyId.value = toRaw(companyId.value);

  searchedParams.value = toRaw(searchParam.value);
  isSearched.value = true;
  // 获取班产量
  // currentYield.value = await getCurrentYield(searchParam.value.workCenterId);

  // 最新表格时间处理
  currentWeekDetail.value = getCurrentWeekDetail(
    searchParam.value,
    freeDetail.value
  );
  // 最新休息日数据
  const arr: any = [];
  currentWeekDetail.value.map((e: any) => {
    if (e.isFree === true) {
      arr.push(
        searchedParams.value.planYear + "-" + e.date.split("/").join("-")
      );
    }
  });
  freeDayDetail.value = arr;

  // 一行表格初始化
  // oneLineTable.value = getOneLineDate(
  //   currentWeekDetail.value,
  //   toRaw(searchParam.value.planYear)
  // );
  // 表格数据处理 mockData
  // tableData.value = resolveSearchData(
  //   data,
  //   currentWeekDetail.value,
  //   toRaw(searchParam.value.planYear)
  // );
  tableLoadRate.value = await calculateLoadRate(data);

  tableData.value = resolveSearchData(
    data,
    currentWeekDetail.value,
    toRaw(searchParam.value.planYear)
  );

  // 计算当前未排数量
  data?.forEach((item, index) => {
    const selfIndex = (index + 1) * 2 - 2;
    computedUnPlanQuantity(selfIndex);
  });

  loading.value = false;

  // 获取当前页面已选的物料号ids
  getSelectedAllocationIds();
};

// 重置
const reset = () => {
  searchParam.value = { ...searchParamInit };
  workShopList.value = [];
  tableData.value = [];
  workCenterDetail.value = {};
  isSearched.value = false;
};

// 获取周列表
const monthOptions = ref<OptionType[]>();

// 获取年度列表
const yearOptions = ref();

// 年度变更重新获取月份
function selectYear(e: number) {
  if (e) {
    searchParam.value = { ...searchParam.value, planWeek: "" };
    monthOptions.value = getMonthList(e);
  } else {
    monthOptions.value = [];
    searchParam.value = { ...searchParam.value, planWeek: "" };
  }
}

// 工厂编号列表
const plantList: any = ref([]);
// 工作中心列表
const workShopList: any = ref([]);

// 当前选中的工厂
const companyId = ref("");
const searchedCompanyId = ref("");
async function selectPlant(e: string) {
  workShopList.value = (await getFirstWorkShopList(e)) ?? [];
  searchParam.value = { ...searchParam.value, workCenterId: "" };
  companyId.value =
    plantList.value.find((item) => item.id === e)?.parentId ?? "";
}

onMounted(async () => {
  userPlantInfo.value?.id && selectPlant(userPlantInfo.value?.id);
  // 获取工厂列表
  plantList.value = await getPlantList();
  // 获取年列表
  yearOptions.value = await getYearList();
  // 获取周搜索列表
  monthOptions.value = getMonthList(currentYear);
  // 表格日期对象 [{date: '05/06', week: 1}, {date: '05/07', week: 2}...]
  currentWeekDetail.value = getCurrentWeekDetail(searchParam.value);
});

// 导入周数据
const weekImportRef = ref();
async function weekImportApiFunc(formdata: FormData, config: any) {
  await request.post("/mdm/mdmmatgroup/upload", formdata, config);
}
const weekBatchImport = () => {
  if (!isSearched.value) {
    ElMessage.error("请切换到对应排产后，再操作");
  } else {
    let params = {
      title: "导入周计划",
      tempApi: "/mdm/mdmmatgroup/exportTemp", //模板下载
      importApi: weekImportApiFunc, // 导入
      getTableList: search, // 成功后回调
    };
    weekImportRef.value.acceptParams(params);
  }
};

// 下载excel
const downLoadExcel = () => {
  if (!isSearched.value) {
    ElMessage.error("请切换到对应排产后，再操作");
  } else {
    useDownload(
      "/mes/mesworkorder/export",
      "计划排程-周排产(落料)",
      searchParam.value,
      true,
      ".xls"
    );
  }
};

// 导入日数据
const dailyImportRef = ref();
async function dailyImportApiFunc(formdata: FormData, config: any) {
  await request.post("/mdm/mdmmatgroup/upload", formdata, config);
}
const dailyBatchImport = () => {
  if (!isSearched.value) {
    ElMessage.error("请切换到对应排产后，再操作");
  } else {
    let params = {
      title: "导入日计划",
      tempApi: "/mdm/mdmmatgroup/exportTemp", //模板下载
      importApi: dailyImportApiFunc, // 导入
      getTableList: search, // 成功后回调
    };
    dailyImportRef.value.acceptParams(params);
  }
};

// 工作中心详情
const workCenterDetail = ref();
// 最大负荷率
const maxCapacityLoad = ref();
// 休息日设定信息
const freeDetail = ref();
// 物料列表
const routingAllocationIdList = ref();
// 日班次
const dateshiftCount = ref();

async function startSearch() {
  tableData.value = [];
  isSearched.value = false;
  if (!searchParam.value.plantId) {
    ElMessage.error("请选择工厂");
    return;
  } else if (!searchParam.value.workCenterId) {
    ElMessage.error("请选择工作中心");
    return;
  } else if (!searchParam.value.planYear) {
    ElMessage.error("请选择年份");
    return;
  } else if (!searchParam.value.planWeek) {
    ElMessage.error("请选择工作周");
    return;
  } else {
    // 工作中心详情
    const { workCenterId, planYear, plantId } = searchParam.value;
    workCenterDetail.value = await getWorkCenterDetail(workCenterId);
    dateshiftCount.value = await getDateshiftCount(searchParam.value);
    if (dateshiftCount.value.length === 0) {
      ElMessage.error("请先设置排班");
      return;
    }
    // 获取最大负荷率
    maxCapacityLoad.value = workCenterDetail.value.maxCapacityLoad;
    // 获取休息日数据
    freeDetail.value = await getFreeDetails(plantId, planYear);
    // 获取物料下拉列表
    routingAllocationIdList.value = await getMaterialList(
      searchParam.value.plantId,
      searchParam.value.workCenterId
    );
    search();
  }
}

// 当前页面已选的物料号ids
const selectedRoutingAllocationIds: any = ref([]);
// 选择物料号
async function changeRoutingAllocation(data: string, index: number) {
  const indexArr = [index, index + 1];
  if (data) {
    const current = routingAllocationIdList.value.filter((e) => e.id === data);
    const res: any = await getCurrentYield(
      searchParam.value.plantId,
      current[0]?.routingId
    );
    indexArr.map((item) => {
      tableData.value[item].requestPlanList = [];
      tableData.value[item].routingAllocationId = current[0]?.id || "";
      tableData.value[item].routingId = current[0]?.routingId || "";
      tableData.value[item].actualYield = res.actualYield;
      tableData.value[item].yield = res.maxYield;
    });
  } else {
    indexArr.map((item) => {
      tableData.value[item].requestPlanList = [];
      tableData.value[item].routingAllocationId = "";
      tableData.value[item].routingId = "";
      tableData.value[item].yield = "";
    });
  }
  getSelectedAllocationIds();
}

// 获取当前页面已选的物料号ids
function getSelectedAllocationIds() {
  const selectArr: any[] = [];
  tableData.value.map((item, index) => {
    if (item.planState * 1 !== 5) {
      selectArr.push(item.routingAllocationId);
    }
  });
  selectedRoutingAllocationIds.value = Array.from(new Set(selectArr));
}

function changePlanQuantity(e, index) {
  // 计算未排数量  待计算  用计划减去每隔的和
  computedUnPlanQuantity(index);
}

// 接口自动分配
async function rulePlanQuantity(e, index) {
  formRef.value
    .validateField(index + ".planQuantity")
    .then(async (res) => {
      const resultTableData = deepCopy(toRaw(tableData.value));
      resultTableData[index].autoAllocation = 1;
      resultTableData[index + 1].autoAllocation = 1;
      const result = resolveSaveData(resultTableData);
      tableData.value[index].autoAllocationLoading = true;
      const { data, code } = await request({
        url: "/mes/mesworkorder/autoAllocation",
        method: "post",
        data: result,
      }).finally(() => {
        tableData.value[index].autoAllocationLoading = true;
      });
      if (code === 200) {
        ElMessage.success(`自动分配成功`);
        tableLoadRate.value = await calculateLoadRate(data);
        tableData.value = resolveSearchData(
          data,
          currentWeekDetail.value,
          toRaw(searchParam.value.planYear)
        );

        // 计算当前未排数量
        data?.forEach((item, index) => {
          const selfIndex = (index + 1) * 2 - 2;
          computedUnPlanQuantity(selfIndex);
        });

        // 获取当前页面已选的物料号ids
        getSelectedAllocationIds();
      }
    })
    .catch(() => {});
}

// 校验当前班次是否存在 planDate计划日期、cellIndex当前班次
function isWorkingCrew(planDates: string, cellIndex: number) {
  let result = false;
  const current = dateshiftCount.value.filter((e: any) =>
    e.planDate.split("/").join("-").includes(planDates)
  );
  if (current && current[0] && current[0].shiftCount > cellIndex) {
    result = true;
  }
  return result;
}

// 计算未排产数量
function computedUnPlanQuantity(index) {
  const indexArr = [index, index + 1];
  let totalQuantity = 0;
  tableData.value[index].newOrders.map((orderItem) => {
    orderItem.newClasses.map((count) => {
      totalQuantity += count.planQuantity * 1;
    });
  });
  // 修改第一行和第二行的值
  indexArr.map((tableIndex) => {
    const computedNumber = Math.floor(
      tableData.value[tableIndex].planQuantity - totalQuantity
    );
    const number = computedNumber < 0 ? 0 : computedNumber;
    tableData.value[tableIndex].unPlanQuantity = number;
  });
}

// 钢卷选择
function selectMaterials(row, rowIndex) {
  formRef.value
    .validateField(rowIndex + ".routingAllocationId")
    .then(async (res) => {
      const { data } = await request({
        url: `/mes/mesroutingbom/listMainMaterial/${row.routingAllocationId}`,
        method: "GET",
        data: {},
      });
      if (!data || !data.length) {
        ElMessage.error("请给当前工序设置卷料");
      } else {
        materialsSelect.eldIds = [];
        if (row.id) {
          const current = elderData.value.filter(
            (item: any) => item.id === row.id
          );
          if (current && current.length) {
            let list: string[] = [];
            current[0].requestPlanList.map((self: any) => {
              list.push(self.materialBarcode);
            });
            materialsSelect.eldIds = list || [];
          }
        }

        materialsSelect.data = row.requestPlanList || [];
        materialsSelect.allocationId = row.routingAllocationId;
        materialsSelect.rowIndex = rowIndex;
        materialsSelect.readonly = row.planState * 1 > 0 ? true : false;
        materialsSelect.visible = true;
      }
    })
    .catch(() => {});
}

const isOverLoadRate = ref(false);

watch(
  () => tableLoadRate.value,
  (newValue) => {
    const overArrs = newValue?.filter(
      (item) => Number(item) > maxCapacityLoad.value / 100
    );
    isOverLoadRate.value = overArrs && overArrs?.length ? true : false;
  },
  {
    deep: true,
  }
);
const saveLoading = ref(false);
function savePlan(resultTableData: any, message: "", idsSave?: any) {
  formRef.value.validate(async (valid: any) => {
    if (valid) {
      const postUrl = resolveUrl(message);
      const idList = message == "删除" ? idsSave : ids.value;

      // 添加selected被选中标识
      resultTableData.forEach((item: any, index: number) => {
        item.selected = 0;
        if (idList.indexOf(item.id) !== -1 || idList.indexOf(item.key) !== -1) {
          item.selected = 1;
        } else {
          item.selected = 0;
        }
      });

      // 已下达数据校验,获取下达时被勾选的数据,判断钢卷和计划数量是否为空
      if (message === "下达") {
        for (let i = 0; i < resultTableData.length; i++) {
          if (
            i % 2 === 0 &&
            resultTableData[i].selected == 1 &&
            resultTableData[i].planState != 5
          ) {
            if (resultTableData[i].requestPlanList.length === 0) {
              ElMessage.error("下达的数据，卷料不能为空");
              return;
            }
            let noPlanQuantity = true;
            for (let j = 0; j < resultTableData[i].newOrders.length; j++) {
              const newClasses = resultTableData[i].newOrders[j].newClasses;
              for (let b = 0; b < newClasses.length; b++) {
                if (
                  newClasses[b].planQuantity &&
                  newClasses[b].planQuantity != 0
                ) {
                  noPlanQuantity = false;
                  break;
                }
              }
            }

            if (noPlanQuantity) {
              ElMessage.error("下达的数据，本周的计划分配数量不能全为空");
              return;
            }
          }
        }
      }

      // 排查当前是否有超负荷率的情况
      if (isOverLoadRate.value) {
        ElMessageBox.confirm(
          "当前生产计划有负荷率超标情况，请确定是否继续操作",
          "提示",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }
        )
          .then(() => {
            lastSubmit(resultTableData, message, postUrl);
          })
          .catch(() => {
            ElMessage({
              type: "info",
              message: "已取消",
            });
          });
      } else {
        lastSubmit(resultTableData, message, postUrl);
      }
    } else {
      ElMessage.warning("请完善基础信息");
    }
  });
}

// 最终操作接口
async function lastSubmit(
  resultTableData: any,
  message: string,
  postUrl: string
) {
  const result = resolveSaveData(resultTableData);
  showLoading(message, true);
  const { data, code } = await request({
    url: postUrl,
    method: "post",
    data: result,
  }).finally(() => {
    showLoading(message, false);
  });
  if (code === 200) {
    ElMessage.success(`${message}成功`);
    search(); // 更新数据
  }
}

function resolveUrl(message) {
  let url = "";
  if (message == "保存") {
    url = "/mes/mesworkorder/saveWeekFirst";
  } else if (message == "下达") {
    url = "/mes/mesworkorder/issuePlan";
  } else if (message == "删除") {
    url = "/mes/mesworkorder/deletePlan";
  } else if (message == "关闭") {
    url = "/mes/mesworkorder/closePlan";
  } else {
    url = "/mes/mesworkorder/saveWeekFirst";
  }
  return url;
}

function showLoading(message, loading) {
  if (message == "保存") {
    saveLoading.value = loading;
  } else if (message == "下达") {
    issueLoading.value = loading;
  } else if (message == "删除") {
    deleteLoading.value = loading;
  } else if (message == "关闭") {
    closeLoading.value = loading;
  }
}

const open = (
  rowData: any,
  rowIndex: number,
  monthIndex: number,
  cellIndex: number,
  quantity: number | string
) => {
  if (rowData.planState * 1 !== 0) {
    return;
  }
  if (
    !isWorkingCrew(
      tableData.value[rowIndex].newOrders[monthIndex].planDate,
      cellIndex
    )
  ) {
    ElMessage.error("当前未设置班次");
    return;
  }
  if (!tableData.value[rowIndex].routingAllocationId) {
    ElMessage.error("请先选择工艺路线");
    return;
  }
  if (tableData.value[rowIndex].planQuantity * 1 === 0) {
    ElMessage.error("请先输入计划数量");
    return;
  }

  if (tableData.value[rowIndex].planState * 1 === 0) {
    dialogVisible.value = true;
    ruleForm.quantity = quantity;
    ruleForm.rowData = rowData;
    ruleForm.rowIndex = rowIndex;
    ruleForm.monthIndex = monthIndex;
    ruleForm.cellIndex = cellIndex;
    ruleForm.unPlanQuantity = tableData.value[rowIndex].unPlanQuantity;
  }
};
</script>
<style lang="scss" scoped>
@import url("./index.scss");

:deep(.planDialog .el-dialog__body) {
  padding: 20px 20px 0px;
}

:deep(.el-table--border th.bg-free) {
  background-color: #fef0f0 !important;
  color: rgba(248, 113, 113, 1) !important;
}

:deep(.percent_cell .cell) {
  width: 100%;
  height: 29px;
  line-height: 29px;
  display: block;
  padding: 0 !important;

  div {
    display: block;
    height: 100%;
    width: 100%;

    span {
      display: block;
      height: 100%;
      width: auto;
      padding: 0 7px;
    }
  }
}
</style>
